package jgo.core;

import jgo.JGo;
import jgo.Plugin;
import org.yaml.snakeyaml.Yaml;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
import java.util.HashMap;

public class ConfigPlugin extends Plugin {
	protected JGo jgo;
	private Map<String, Object> config;
	private String configFile;

	public ConfigPlugin(String configFile) {
		this.configFile = configFile.startsWith("/") ? configFile : "/" + configFile;
	}

	@Override
	public void init(JGo jgo) {
		this.jgo = jgo;
		loadConfig();
	}

	protected void loadConfig() {
		try (InputStream inputStream = getClass().getResourceAsStream(configFile)) {
			if (inputStream == null) {
				throw new RuntimeException("Config file not found: " + configFile);
			}

			if (configFile.endsWith(".yml") || configFile.endsWith(".yaml")) {
				Yaml yaml = new Yaml();
				config = yaml.load(inputStream);
			} else if (configFile.endsWith(".json")) {
				ObjectMapper mapper = new ObjectMapper();
				config = mapper.readValue(inputStream, Map.class);
			} else if (configFile.endsWith(".properties")) {
				Properties props = new Properties();
				props.load(inputStream);
				config = new HashMap<String, Object>((Map) props);
			} else {
				throw new RuntimeException("Unsupported config file type: " + configFile);
			}
			
			// 打印配置内容
			printConfig();
		} catch (Exception e) {
			jgo.logger.error("Failed to load config file: " + configFile, e);
			throw new RuntimeException("Failed to load config", e);
		}
	}

	// 新增方法：打印配置内容
	private void printConfig() {
		jgo.logger.info("Loaded configuration from: {}", configFile);
		jgo.logger.info("Configuration contents:");
		printConfigRecursive(config, 0);
	}

	private void printConfigRecursive(Map<String, Object> map, int indent) {
		for (Map.Entry<String, Object> entry : map.entrySet()) {
			String indentation = createIndentation(indent);
			if (entry.getValue() instanceof Map) {
				jgo.logger.info("{}{}:", indentation, entry.getKey());
				printConfigRecursive((Map<String, Object>) entry.getValue(), indent + 1);
			} else {
				jgo.logger.info("{}{}: {}", indentation, entry.getKey(), entry.getValue());
			}
		}
	}

	private String createIndentation(int indent) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < indent; i++) {
			sb.append("  ");
		}
		return sb.toString();
	}

	public String getConfig(String key) {
		Object value = getConfigValue(key);
		return value != null ? value.toString() : null;
	}

	public String getConfig(String pluginName, String key) {
		return getConfig(pluginName + "." + key);
	}

	public <T> T getConfig(String key, Class<T> type) {
		Object value = getConfigValue(key);
		if (value == null) {
			return null;
		}
		if (type.isInstance(value)) {
			return type.cast(value);
		}
		throw new ClassCastException("Cannot cast " + value.getClass() + " to " + type);
	}

	public <T> T getConfig(String pluginName, String key, Class<T> type) {
		return getConfig(pluginName + "." + key, type);
	}

	private Object getConfigValue(String key) {
		String[] parts = key.split("\\.");
		Map<String, Object> current = config;
		for (int i = 0; i < parts.length - 1; i++) {
			Object value = current.get(parts[i]);
			if (!(value instanceof Map)) {
				return null;
			}
			current = (Map<String, Object>) value;
		}
		return current.get(parts[parts.length - 1]);
	}

	public static ConfigPlugin yaml(String configFile) {
		return new ConfigPlugin(configFile);
	}

	public static ConfigPlugin json(String configFile) {
		return new ConfigPlugin(configFile);
	}

	public static ConfigPlugin properties(String configFile) {
		return new ConfigPlugin(configFile);
	}
	//测试
	public static void main(String[] args) {
		JGo app = new JGo();
		app.use(new ConfigPlugin("/config.properties"));
		// 不需要调用 run() 方法，因为我们只是想测试配置加载
	}
}